﻿/*
// CHANGE LOG
mod 16 jun 07 - ddb
	ver 1.02
	changed:
		-  removed conditional in <img loading that only monitored load progress if width and height attributes
		were NOT found, now is monitoring load regardless of width/height attributes
		-  added some Math.floor() and Math.ceil() to the resizeTextBox() methods to help eliminate
		the thin gap-spaces between the tiles when resizing
		-  resized all tiles in the rolloverScale9_mc to whole pixel dimensions (38.0x26.0) and repositioned on whole pixels (38,0)
	added:
		toString() method
		className_str:String
		version_str:String

*/
/*
// METHOD TABLE:

function ScaleNineTextbox() {
public function setText(p_sText:String, p_maxWidth_num:Number, p_leftMargin_num:Number, p_topMargin_num:Number, p_rightMargin_num:Number):Void {
public function clearText() {
private function resizeTextBox() {
private function resetTextBox() {
private function setWidth(p_newWidth_numidth) {
private function onAllImagesLoaded(imgClips_array:Array):Void {
private function getMcsFromHtmlText(strText:String):Array {
private function toString():Void{
*/
class com.utils.ScaleNineTextbox extends MovieClip {
	private var className_str:String;
	private var version_str:String;
	// properties
	//
	// UI objects
	private var upperRow_mc:MovieClip;
	private var centerRow_mc:MovieClip;
	private var lowerRow_mc:MovieClip;
	private var body_txt:TextField;
	// metrics
	private var newWidth_num:Number;
	private var newHeight_num:Number;
	private var leftMargin_num:Number;
	private var topMargin_num:Number;
	private var rightMargin_num:Number;
	// interval ID for embedded html image loading loop
	private var loadingImagesID_num:Number;
	//
	// Constructor
	function ScaleNineTextbox() {
		className_str = "  ScaleNineTextbox";
		version_str = "v1.02";
		// when extending MovieClip, this refers to Movieclip instance name
		//trace(this);
		// init defaults
		newWidth_num = _width;
		body_txt.autoSize = "left";
		body_txt.html = true;
		topMargin_num = 10;
		leftMargin_num = rightMargin_num = 4;
	}
	//
	public function setText(p_sText:String, p_maxWidth_num:Number, p_leftMargin_num:Number, p_topMargin_num:Number, p_rightMargin_num:Number):Void {
		//trace("setText()");
		if (p_leftMargin_num != undefined) {
			leftMargin_num = p_leftMargin_num;
		}
		if (p_topMargin_num != undefined) {
			topMargin_num = p_topMargin_num;
		}
		if (p_rightMargin_num == undefined) {
			rightMargin_num = leftMargin_num;
		} else {
			rightMargin_num = p_rightMargin_num;
		}
		body_txt._y = topMargin_num;
		body_txt._x = leftMargin_num;
		body_txt.html = true;
		body_txt.htmlText = p_sText;
		// set width
		setWidth(p_maxWidth_num);
		// check htmlText for embedded images ('<img>')
		checkForImages(p_sText);
	}
	//
	private function setWidth(p_newWidth_num):Void {
		//trace("setWidth()");
		newWidth_num = Math.ceil(p_newWidth_num);
		resizeTextBox();
	}
	//
	private function resizeTextBox():Void {
		//trace("  resizeTextBox()");
		body_txt._width = newWidth_num - leftMargin_num - rightMargin_num;
		newHeight_num = Math.ceil(body_txt._height);
		var nI:Number = 1;
		centerRow_mc._height = 1;
		var txtHeightOffset = newHeight_num - Math.ceil((lowerRow_mc._height - topMargin_num / 2));
		// - 30;
		//
		do {
			nI++;
		} while (nI * centerRow_mc._height < txtHeightOffset);
		//
		centerRow_mc._y = upperRow_mc._height;
		centerRow_mc._height = Math.ceil(centerRow_mc._height * nI);
		lowerRow_mc._y = Math.floor(centerRow_mc._height + upperRow_mc._height);
		//set the new widths
		var nAdjW:Number = newWidth_num - upperRow_mc.leftColumn_mc._width - upperRow_mc.rightColumn_mc._width;
		upperRow_mc.middleColumn_mc._x = centerRow_mc.middleColumn_mc._x = lowerRow_mc.middleColumn_mc._x = upperRow_mc.leftColumn_mc._width;
		upperRow_mc.middleColumn_mc._width = centerRow_mc.middleColumn_mc._width = lowerRow_mc.middleColumn_mc._width = nAdjW;
		upperRow_mc.rightColumn_mc._x = centerRow_mc.rightColumn_mc._x = lowerRow_mc.rightColumn_mc._x = upperRow_mc.leftColumn_mc._width + upperRow_mc.middleColumn_mc._width;
	}
	//
	public function clearText():Void {
		body_txt.htmlText = "";
		resetTextBox();
	}
	//
	private function resetTextBox():Void {
		//trace("resetTextBox()");
		upperRow_mc.middleColumn_mc._xscale = centerRow_mc.middleColumn_mc._xscale = lowerRow_mc.middleColumn_mc._xscale = 100;
		upperRow_mc.rightColumn_mc._x = centerRow_mc.rightColumn_mc._x = lowerRow_mc.rightColumn_mc._x = upperRow_mc.leftColumn_mc._width + upperRow_mc.middleColumn_mc._width;
		centerRow_mc._yscale = 100;
		lowerRow_mc._y = centerRow_mc._height + upperRow_mc._height;
	}
	//
	private function checkForImages(p_sText:String):Void{
		if (p_sText.indexOf("<img") != -1) {
			//trace("  found \"<img\". monitoring load progress");
			// content string contains image tags. The images load asynchronously. The textfield will be too small
			// unless:
			//		1. the <img> tag specified width and height attributes,
			//		   in which case the textfield adjusts automatically for each image
			//
			//		OR
			// 
			// 		2. the <img> tag specified an id attribute
			//		   in which case a movieclip was created with that id name, nested within the textfield.
			//		   we can use getBytesTotal/Loaded and monitor the load progress of each image
			//		   and trigger the resizeTextBox() method after all images have been loaded
//			if (p_sText.indexOf("width") == -1 || p_sText.indexOf("height") == -1) {
				// if it doesn't have both width and height attributes
				//trace("    <img> is missing width and/or height attributes");
				clearInterval(loadingImagesID_num);
				loadingImagesID_num = setInterval(this, "onAllImagesLoaded", 100, getMcsFromHtmlText(p_sText));
//			} else {
				//trace("    <img> has width and height attributes");
//			}
		} else {
			//trace("  \"<img\" NOT found in string");
		}

	}
	private function onAllImagesLoaded(imgClips_array:Array):Void {
		//trace("onAllImagesLoaded()");
		var loadCompleteCount:Number = 0;
		for (var i:Number = 0; i < imgClips_array.length; i++) {
			var clipName:String = imgClips_array[i];
			var clip:MovieClip = body_txt[clipName];
			var loadedBytes = clip.getBytesLoaded();
			var totalBytes = clip.getBytesTotal();
			//trace("  is "+loadedBytes+" > 4 && is "+loadedBytes+" >= "+totalBytes);
			if (loadedBytes > 4 && loadedBytes >= totalBytes) {
				//trace("    yes");
				loadCompleteCount++;
			} else {
				//trace("    no");
			}
		}
		if (loadCompleteCount == imgClips_array.length) {
			clearInterval(loadingImagesID_num);
			//trace("  " + loadCompleteCount + " of " + imgClips_array.length + " images loaded");
			resizeTextBox();
		}
	}
	//
	private function getMcsFromHtmlText(strText:String):Array {
		// this function based on code posted by user 'mrand01'
		// http://www.actionscript.org/forums/showthread.php3?p=535518
		// requires that the <img> tag include an id attribute, using single quotes
		// as in: <img id='bullet' src='images/bullet.jpg'>
		// TextField's create a nested MovieClip within the TextField for each <img> tag
		// and use the id attribute as an instance name for that movieclip
		// which is used to monitor loading
		var nImages:Number = strText.split("<img").length - 1;
		var nImageIndex:Number = 0;
		var arrMcs:Array = new Array();
		for (var i:Number = 0; i < nImages; i++) {
			var strImageTag:String;
			var strMcName:String;
			var nFirstQuoteIndex:Number;
			var nLastQuoteIndex:Number;
			nImageIndex = strText.indexOf("<img", nImageIndex);
			strImageTag = strText.substring(nImageIndex, strText.indexOf(">", nImageIndex) + 1);
			if (strImageTag.indexOf("id=") != -1) {
				// looking for double-quote character surrounding id attribute
				nFirstQuoteIndex = strImageTag.indexOf("\"", strImageTag.indexOf("id=")) + 1;
				nLastQuoteIndex = strImageTag.indexOf("\"", nFirstQuoteIndex + 1);
				strMcName = strImageTag.substring(nFirstQuoteIndex, nLastQuoteIndex);
				//trace("  <img id=\"" + strMcName + "\">");
				arrMcs.push(strMcName);
			}
			nImageIndex += strImageTag.length;
		}
		return arrMcs;
	}
	private function toString():String {
		return className_str + " ("+version_str+")";
	}
}
